<?php

namespace JsSdk;

class JsSdk {
	private $appId;
	private $appSecret;
	public function __construct($appId, $appSecret) {
		$this->appId = $appId;
		$this->appSecret = $appSecret;
	}
	public function getsignPackage() {
		$jsapiTicket = $this->getJsApiTicket ();
		
		// 注意 URL 一定要动态获取，不能 hardcode.
		$protocol = (! empty ( $_SERVER ['HTTPS'] ) && $_SERVER ['HTTPS'] !== 'off' || $_SERVER ['SERVER_PORT'] == 443||(isset($_SERVER['HTTP_X_FORWARDED_PROTO']) && $_SERVER['HTTP_X_FORWARDED_PROTO'] === 'https')) ? "https://" : "http://";
		$url = "$protocol$_SERVER[HTTP_HOST]$_SERVER[REQUEST_URI]";
	
		$timestamp = time ();
		$nonceStr = $this->createNonceStr ();
		
		// 这里参数的顺序要按照 key 值 ASCII 码升序排序
		$string = "jsapi_ticket=$jsapiTicket&noncestr=$nonceStr&timestamp=$timestamp&url=$url";
		
		$signature = sha1 ( $string );
		
		$signPackage = array (
				"appId" => $this->appId,
				"nonceStr" => $nonceStr,
				"timestamp" => $timestamp,
				"url" => $url,
				"signature" => $signature,
				"rawString" => $string 
		);
		return $signPackage;
	}
	private function createNonceStr($length = 16) {
		$chars = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";
		$str = "";
		for($i = 0; $i < $length; $i ++) {
			$str .= substr ( $chars, mt_rand ( 0, strlen ( $chars ) - 1 ), 1 );
		}
		return $str;
	}
	private function getJsApiTicket() {
		$data = Cache::get ( 'jssdk_getJsApiTicket'.$this->appId );
		
		if (! $data) {
			$accessToken = $this->getAccessToken ();
			$url = "https://api.weixin.qq.com/cgi-bin/ticket/getticket?type=jsapi&access_token=$accessToken";
			$res = json_decode ( $this->get_data ( $url ),true );
			//print_r($res);
			$data = $res['ticket'];
			if ($data) {
				Cache::set ( 'jssdk_getJsApiTicket'.$this->appId, $data, $res['expires_in'] );
			}
		}
		return $data;
	}
    private function getAccessToken($update = false) {
		//$token=model("apps")->where(array('appid'=>$this->appId))->getField('token');
		$access_token = $this->get_access_token_by_apppid($this->appId, $this->appSecret,$update);

		if ($update == false) {
			$url = 'https://api.weixin.qq.com/cgi-bin/getcallbackip?access_token=' . $access_token;
			$res = json_decode ( $this->get_data ( $url ), true );
			if (isset ( $res ['errcode'] ) && $res ['errcode'] == '40001') {
				$access_token = $this->getAccessToken ( true );
			}
		}
		
		return $access_token;
		//return get_access_token("gh_af977572cf72");
	}
	function get_access_token_by_apppid($appid, $secret, $update = false) {
		if (empty ( $appid ) || empty ( $secret )) {
			return 0;
		}
		
		$key = 'access_token_apppid_' . $appid . '_' . $secret;
		$res = Cache::get( $key );
		if ($res !== false && ! $update)
			return $res;
		
		$url = 'https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&secret=' . $secret . '&appid=' . $appid;
		$tempArr = json_decode ( $this->get_data ( $url ), true );
		if (@array_key_exists ( 'access_token', $tempArr )) {
			Cache::set ( $key, $tempArr ['access_token'], $tempArr ['expires_in'] );
			return $tempArr ['access_token'];
		} else {
			return 0;
		}
	}
	// 以GET方式获取数据，替代file_get_contents
	function get_data($url, $timeout = 5) {
		$msg = $flat = '';
		if (strpos ( $url, 'http://' ) !== false || strpos ( $url, 'https://' ) !== false) {
			
			$ch = curl_init ();
			curl_setopt ( $ch, CURLOPT_URL, $url );
			curl_setopt ( $ch, CURLOPT_RETURNTRANSFER, 1 );
			curl_setopt ( $ch, CURLOPT_CONNECTTIMEOUT, $timeout );
			
			curl_setopt ( $ch, CURLOPT_SSL_VERIFYPEER, FALSE ); // 跳过证书检查
			curl_setopt ( $ch, CURLOPT_SSL_VERIFYHOST, FALSE ); // 不检查证书
			$res = curl_exec ( $ch );
			
			$flat = curl_errno ( $ch );
			if ($flat) {
				$msg = curl_error ( $ch );
			}
			curl_close ( $ch );
		} else {
			$context = stream_context_create ( array (
					'http' => array (
							'timeout' => 30 
					) 
			) ); // 超时时间，单位为秒
			
			$res = file_get_contents ( $url, 0, $context );
		}
		// add_request_log ( $url, '', $res, $flat, $msg );
		
		return $res;
	}
	private function httpGet($url) {
		$curl = curl_init ();
		curl_setopt ( $curl, CURLOPT_RETURNTRANSFER, true );
		curl_setopt ( $curl, CURLOPT_TIMEOUT, 500 );
		curl_setopt ( $curl, CURLOPT_SSL_VERIFYPEER, false );
		curl_setopt ( $curl, CURLOPT_SSL_VERIFYHOST, false );
		curl_setopt ( $curl, CURLOPT_URL, $url );
		
		$res = curl_exec ( $curl );
		curl_close ( $curl );
		
		return $res;
	}
}

